{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "executionInfo": {
     "elapsed": 7240,
     "status": "ok",
     "timestamp": 1649957388239,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "xbFsRsPUGGAL"
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import gymnasium as gym\n",
    "from tqdm import tqdm\n",
    "import random\n",
    "import rl_utils\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch.distributions import Normal\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 147903,
     "status": "ok",
     "timestamp": 1649957536139,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "CDTugDpbGGAM",
    "outputId": "6e1aa92f-700b-49db-9467-21172ce3c64a"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Iteration 0:   0%|          | 0/10 [00:00<?, ?it/s]/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:61: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at  ../torch/csrc/utils/tensor_new.cpp:201.)\n",
      "Iteration 0: 100%|██████████| 10/10 [00:08<00:00,  1.23it/s, episode=10, return=-1534.655]\n",
      "Iteration 1: 100%|██████████| 10/10 [00:15<00:00,  1.52s/it, episode=20, return=-1085.715]\n",
      "Iteration 2: 100%|██████████| 10/10 [00:15<00:00,  1.53s/it, episode=30, return=-364.507]\n",
      "Iteration 3: 100%|██████████| 10/10 [00:15<00:00,  1.53s/it, episode=40, return=-222.485]\n",
      "Iteration 4: 100%|██████████| 10/10 [00:15<00:00,  1.58s/it, episode=50, return=-157.978]\n",
      "Iteration 5: 100%|██████████| 10/10 [00:15<00:00,  1.55s/it, episode=60, return=-166.056]\n",
      "Iteration 6: 100%|██████████| 10/10 [00:15<00:00,  1.55s/it, episode=70, return=-143.147]\n",
      "Iteration 7: 100%|██████████| 10/10 [00:15<00:00,  1.57s/it, episode=80, return=-127.939]\n",
      "Iteration 8: 100%|██████████| 10/10 [00:15<00:00,  1.55s/it, episode=90, return=-180.905]\n",
      "Iteration 9: 100%|██████████| 10/10 [00:15<00:00,  1.53s/it, episode=100, return=-171.265]\n"
     ]
    }
   ],
   "source": [
    "##  构造策略网络的\n",
    "class PolicyNetContinuous(torch.nn.Module):\n",
    "    def __init__(self, state_dim, hidden_dim, action_dim, action_bound):\n",
    "        super(PolicyNetContinuous, self).__init__()\n",
    "        self.fc1 = torch.nn.Linear(state_dim, hidden_dim)\n",
    "        self.fc_mu = torch.nn.Linear(hidden_dim, action_dim)\n",
    "        self.fc_std = torch.nn.Linear(hidden_dim, action_dim)\n",
    "        self.action_bound = action_bound\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.fc1(x))\n",
    "        mu = self.fc_mu(x)\n",
    "        std = F.softplus(self.fc_std(x))  ## 激活函数的，>0，和relu类似\n",
    "        dist = Normal(mu, std)\n",
    "        normal_sample = dist.rsample()  # rsample()是重参数化采样，单独的高斯分布采样不可导，重参数化可导的\n",
    "        log_prob = dist.log_prob(normal_sample) ##  从分布内采样概率，并算出概率的log值\n",
    "        action = torch.tanh(normal_sample)    ## 确定性策略输出的动作值，不是概率的，分布在 -1到1 之间\n",
    "        # 计算tanh_normal分布的对数概率密度\n",
    "        ## 熵的相反数\n",
    "        log_prob = log_prob - torch.log(1 - torch.tanh(action).pow(2) + 1e-7)\n",
    "        action = action * self.action_bound   ## 输出动作的，缩放到区间内\n",
    "        return action, log_prob\n",
    "\n",
    "## 状态动作价值网络，输出状态动作对 (状态，动作) 的价值\n",
    "## 也就是动作价值网络\n",
    "class QValueNetContinuous(torch.nn.Module):\n",
    "    def __init__(self, state_dim, hidden_dim, action_dim):\n",
    "        super(QValueNetContinuous, self).__init__()\n",
    "        self.fc1 = torch.nn.Linear(state_dim + action_dim, hidden_dim)\n",
    "        self.fc2 = torch.nn.Linear(hidden_dim, hidden_dim)\n",
    "        self.fc_out = torch.nn.Linear(hidden_dim, 1)\n",
    "\n",
    "    ## 输入 (状态，动作)\n",
    "    def forward(self, x, a):\n",
    "        cat = torch.cat([x, a], dim=1) # 拼接状态和动作\n",
    "        x = F.relu(self.fc1(cat))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        return self.fc_out(x)\n",
    "\n",
    "class SACContinuous:\n",
    "    ''' 处理连续动作的SAC算法 '''\n",
    "    def __init__(self, state_dim, hidden_dim, action_dim, action_bound,\n",
    "                 actor_lr, critic_lr, alpha_lr, target_entropy, tau, gamma,\n",
    "                 device):\n",
    "        self.actor = PolicyNetContinuous(state_dim, hidden_dim, action_dim,\n",
    "                                         action_bound).to(device)  # 策略网络\n",
    "        self.critic_1 = QValueNetContinuous(state_dim, hidden_dim,\n",
    "                                            action_dim).to(device)  # 第一个Q网络\n",
    "        self.critic_2 = QValueNetContinuous(state_dim, hidden_dim,\n",
    "                                            action_dim).to(device)  # 第二个Q网络\n",
    "        self.target_critic_1 = QValueNetContinuous(state_dim,\n",
    "                                                   hidden_dim, action_dim).to(\n",
    "                                                       device)  # 第一个目标Q网络\n",
    "        self.target_critic_2 = QValueNetContinuous(state_dim,\n",
    "                                                   hidden_dim, action_dim).to(\n",
    "                                                       device)  # 第二个目标Q网络\n",
    "        # 令目标Q网络的初始参数和Q网络一样\n",
    "        self.target_critic_1.load_state_dict(self.critic_1.state_dict())\n",
    "        self.target_critic_2.load_state_dict(self.critic_2.state_dict())\n",
    "        self.actor_optimizer = torch.optim.Adam(self.actor.parameters(),\n",
    "                                                lr=actor_lr)\n",
    "        self.critic_1_optimizer = torch.optim.Adam(self.critic_1.parameters(),\n",
    "                                                   lr=critic_lr)\n",
    "        self.critic_2_optimizer = torch.optim.Adam(self.critic_2.parameters(),\n",
    "                                                   lr=critic_lr)\n",
    "        # 使用alpha的log值,可以使训练结果比较稳定\n",
    "        self.log_alpha = torch.tensor(np.log(0.01), dtype=torch.float)\n",
    "        ## update 熵系数\n",
    "        self.log_alpha.requires_grad = True  # 可以对alpha求梯度\n",
    "        self.log_alpha_optimizer = torch.optim.Adam([self.log_alpha],\n",
    "                                                    lr=alpha_lr)\n",
    "        self.target_entropy = target_entropy  # 目标熵的大小\n",
    "        self.gamma = gamma\n",
    "        self.tau = tau\n",
    "        self.device = device\n",
    "\n",
    "    def take_action(self, state):\n",
    "        state = torch.tensor([state], dtype=torch.float).to(self.device)\n",
    "        action = self.actor(state)[0] ## 拿到确定性策略 网络的输出，也就是确定的动作\n",
    "        return [action.item()]\n",
    "\n",
    "    def calc_target(self, rewards, next_states, dones):  # 计算目标Q值\n",
    "        next_actions, log_prob = self.actor(next_states)\n",
    "        entropy = -log_prob ## 熵\n",
    "        q1_value = self.target_critic_1(next_states, next_actions) ## 目标价值网络的下个状态的价值输出\n",
    "        q2_value = self.target_critic_2(next_states, next_actions)\n",
    "        ## 拿到最小的价值输出，然后加上熵，就是目标的下个状态的价值\n",
    "        next_value = torch.min(q1_value,\n",
    "                               q2_value) + self.log_alpha.exp() * entropy\n",
    "        ## 目标当前状态的价值，时序差分的公式\n",
    "        td_target = rewards + self.gamma * next_value * (1 - dones)\n",
    "        return td_target\n",
    "\n",
    "    def soft_update(self, net, target_net):\n",
    "        ## 延迟update，EMA update，每次 update 很少的部分的\n",
    "        for param_target, param in zip(target_net.parameters(), net.parameters()):\n",
    "            param_target.data.copy_(param_target.data * (1.0 - self.tau) + param.data * self.tau)\n",
    "\n",
    "    def update(self, transition_dict):\n",
    "        ## 拿到这条序列内的 状态、动作和奖励，下一个状态、是否完成的\n",
    "        states = torch.tensor(transition_dict['states'],\n",
    "                              dtype=torch.float).to(self.device)\n",
    "        actions = torch.tensor(transition_dict['actions'],\n",
    "                               dtype=torch.float).view(-1, 1).to(self.device)\n",
    "        rewards = torch.tensor(transition_dict['rewards'],\n",
    "                               dtype=torch.float).view(-1, 1).to(self.device)\n",
    "        next_states = torch.tensor(transition_dict['next_states'],\n",
    "                                   dtype=torch.float).to(self.device)\n",
    "        dones = torch.tensor(transition_dict['dones'],\n",
    "                             dtype=torch.float).view(-1, 1).to(self.device)\n",
    "        # 和之前章节一样,对倒立摆环境的奖励进行重塑以便训练\n",
    "        rewards = (rewards + 8.0) / 8.0\n",
    "\n",
    "        # 更新两个Q网络\n",
    "        ## 用下一个（状态、动作）对的动作价值 Q，然后间接求出当前的（状态、动作）对的动作价值\n",
    "        td_target = self.calc_target(rewards, next_states, dones)\n",
    "        ## 直接求出当前（状态、动作）的动作价值，和 间接求出的动作价值，使用 MSE 来算损失函数的，q_targets不反向传播求梯度\n",
    "        critic_1_loss = torch.mean(\n",
    "            F.mse_loss(self.critic_1(states, actions), td_target.detach()))\n",
    "        critic_2_loss = torch.mean(\n",
    "            F.mse_loss(self.critic_2(states, actions), td_target.detach()))\n",
    "        self.critic_1_optimizer.zero_grad() ## 价值网络的参数梯度置零的\n",
    "        critic_1_loss.backward() ## 价值网络的损失loss反向传播梯度\n",
    "        self.critic_1_optimizer.step() ## update 网络\n",
    "        self.critic_2_optimizer.zero_grad()\n",
    "        critic_2_loss.backward()\n",
    "        self.critic_2_optimizer.step()\n",
    "\n",
    "        # 更新策略网络\n",
    "        ## self.actor(states) 是输出当前状态的动作，以及熵的相反数\n",
    "        new_actions, log_prob = self.actor(states)\n",
    "        entropy = -log_prob ## 熵\n",
    "        ## 此时的动作价值网络已经 update 了的\n",
    "        q1_value = self.critic_1(states, new_actions)\n",
    "        q2_value = self.critic_2(states, new_actions)\n",
    "        ## update以后的动作价值网络，使用当前的（状态、动作）的动作价值，加了负号的，也就是最大化动作价值的\n",
    "        actor_loss = torch.mean(-self.log_alpha.exp() * entropy -\n",
    "                                torch.min(q1_value, q2_value))\n",
    "        self.actor_optimizer.zero_grad()\n",
    "        actor_loss.backward()\n",
    "        self.actor_optimizer.step()\n",
    "\n",
    "        # 更新alpha值\n",
    "        alpha_loss = torch.mean(\n",
    "            (entropy - self.target_entropy).detach() * self.log_alpha.exp())\n",
    "        self.log_alpha_optimizer.zero_grad()\n",
    "        alpha_loss.backward()\n",
    "        self.log_alpha_optimizer.step()\n",
    "\n",
    "        self.soft_update(self.critic_1, self.target_critic_1)\n",
    "        self.soft_update(self.critic_2, self.target_critic_2)\n",
    "\n",
    "env_name = 'Pendulum-v1'\n",
    "env = gym.make(env_name, render_mode=\"rgb_array\")\n",
    "state_dim = env.observation_space.shape[0]\n",
    "action_dim = env.action_space.shape[0]\n",
    "action_bound = env.action_space.high[0]  # 动作最大值\n",
    "random.seed(0)\n",
    "np.random.seed(0)\n",
    "_ = env.reset(seed=0)\n",
    "torch.manual_seed(0)\n",
    "\n",
    "actor_lr = 3e-4\n",
    "critic_lr = 3e-3\n",
    "alpha_lr = 3e-4\n",
    "num_episodes = 100\n",
    "hidden_dim = 128\n",
    "gamma = 0.99\n",
    "tau = 0.005  # 软更新参数\n",
    "buffer_size = 100000\n",
    "minimal_size = 1000\n",
    "batch_size = 64\n",
    "target_entropy = -env.action_space.shape[0]\n",
    "device = torch.device(\"cuda\") if torch.cuda.is_available() else torch.device(\n",
    "    \"cpu\")\n",
    "\n",
    "replay_buffer = rl_utils.ReplayBuffer(buffer_size)\n",
    "agent = SACContinuous(state_dim, hidden_dim, action_dim, action_bound,\n",
    "                      actor_lr, critic_lr, alpha_lr, target_entropy, tau,\n",
    "                      gamma, device)\n",
    "\n",
    "##  此处只会用来 train SAC智能体，并将智能体和环境交互产生的交互数据，加入到历史数据回放池\n",
    "return_list = rl_utils.train_off_policy_agent(env, agent, num_episodes,\n",
    "                                              replay_buffer, minimal_size,\n",
    "                                              batch_size)\n",
    "\n",
    "# Iteration 0: 100%|██████████| 10/10 [00:08<00:00,  1.19it/s, episode=10,\n",
    "# return=-1534.655]\n",
    "# Iteration 1: 100%|██████████| 10/10 [00:16<00:00,  1.62s/it, episode=20,\n",
    "# return=-1085.715]\n",
    "# Iteration 2: 100%|██████████| 10/10 [00:16<00:00,  1.66s/it, episode=30,\n",
    "# return=-377.923]\n",
    "# Iteration 3: 100%|██████████| 10/10 [00:16<00:00,  1.66s/it, episode=40,\n",
    "# return=-284.440]\n",
    "# Iteration 4: 100%|██████████| 10/10 [00:17<00:00,  1.73s/it, episode=50,\n",
    "# return=-183.556]\n",
    "# Iteration 5: 100%|██████████| 10/10 [00:17<00:00,  1.76s/it, episode=60,\n",
    "# return=-202.841]\n",
    "# Iteration 6: 100%|██████████| 10/10 [00:17<00:00,  1.75s/it, episode=70,\n",
    "# return=-193.436]\n",
    "# Iteration 7: 100%|██████████| 10/10 [00:17<00:00,  1.76s/it, episode=80,\n",
    "# return=-131.132]\n",
    "# Iteration 8: 100%|██████████| 10/10 [00:17<00:00,  1.73s/it, episode=90,\n",
    "# return=-181.888]\n",
    "# Iteration 9: 100%|██████████| 10/10 [00:17<00:00,  1.73s/it, episode=100,\n",
    "# return=-139.574]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 295
    },
    "executionInfo": {
     "elapsed": 21,
     "status": "ok",
     "timestamp": 1649957536140,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "aMCsA4pIGGAT",
    "outputId": "101695cb-9b15-42fe-ffec-a9cc906ca32e"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "episodes_list = list(range(len(return_list)))\n",
    "plt.plot(episodes_list, return_list)\n",
    "plt.xlabel('Episodes')\n",
    "plt.ylabel('Returns')\n",
    "plt.title('SAC on {}'.format(env_name))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "executionInfo": {
     "elapsed": 509,
     "status": "ok",
     "timestamp": 1649957536632,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "DzjlOQMyGGAU",
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "## 网络结构和上面的SAC是相同的，主要区别在 train 的地方\n",
    "class CQL:\n",
    "    ''' CQL算法 '''\n",
    "    def __init__(self, state_dim, hidden_dim, action_dim, action_bound,\n",
    "                 actor_lr, critic_lr, alpha_lr, target_entropy, tau, gamma,\n",
    "                 device, beta, num_random):\n",
    "        self.actor = PolicyNetContinuous(state_dim, hidden_dim, action_dim,\n",
    "                                         action_bound).to(device)  # 策略网络\n",
    "        self.critic_1 = QValueNetContinuous(state_dim, hidden_dim,\n",
    "                                            action_dim).to(device)  # 第一个Q网络\n",
    "        self.critic_2 = QValueNetContinuous(state_dim, hidden_dim,\n",
    "                                            action_dim).to(device)  # 第二个Q网络\n",
    "        self.target_critic_1 = QValueNetContinuous(state_dim, hidden_dim,\n",
    "                                                   action_dim).to(device)  # 第一个目标Q网络\n",
    "        self.target_critic_2 = QValueNetContinuous(state_dim, hidden_dim,\n",
    "                                                   action_dim).to(device)  # 第二个目标Q网络\n",
    "        # 令目标Q网络的初始参数和Q网络一样\n",
    "        self.target_critic_1.load_state_dict(self.critic_1.state_dict())\n",
    "        self.target_critic_2.load_state_dict(self.critic_2.state_dict())\n",
    "        ## 配置网络的优化器\n",
    "        self.actor_optimizer = torch.optim.Adam(self.actor.parameters(),\n",
    "                                                lr=actor_lr)\n",
    "        self.critic_1_optimizer = torch.optim.Adam(self.critic_1.parameters(),\n",
    "                                                   lr=critic_lr)\n",
    "        self.critic_2_optimizer = torch.optim.Adam(self.critic_2.parameters(),\n",
    "                                                   lr=critic_lr)\n",
    "        # 使用alpha的log值,可以使训练结果比较稳定\n",
    "        self.log_alpha = torch.tensor(np.log(0.01), dtype=torch.float)\n",
    "        ## update 熵系数\n",
    "        self.log_alpha.requires_grad = True  #对alpha求梯度\n",
    "        self.log_alpha_optimizer = torch.optim.Adam([self.log_alpha],\n",
    "                                                    lr=alpha_lr)\n",
    "        self.target_entropy = target_entropy  # 目标熵的大小\n",
    "        self.gamma = gamma\n",
    "        self.tau = tau\n",
    "\n",
    "        self.beta = beta  # CQL损失函数中的系数\n",
    "        self.num_random = num_random  # CQL中的动作采样数\n",
    "\n",
    "    def take_action(self, state):\n",
    "        state = torch.tensor([state], dtype=torch.float).to(device)\n",
    "        action = self.actor(state)[0] ## 拿到确定性策略 网络的输出，也就是确定的动作\n",
    "        return [action.item()]\n",
    "\n",
    "    def soft_update(self, net, target_net):\n",
    "        ## 延迟update，EMA update，每次 update 很少的部分的\n",
    "        for param_target, param in zip(target_net.parameters(),\n",
    "                                       net.parameters()):\n",
    "            param_target.data.copy_(param_target.data * (1.0 - self.tau) +\n",
    "                                    param.data * self.tau)\n",
    "\n",
    "    def update(self, transition_dict):\n",
    "        ## 拿到这条序列内的 状态、动作和奖励，下一个状态、是否完成的\n",
    "        states = torch.tensor(transition_dict['states'],\n",
    "                              dtype=torch.float).to(device)\n",
    "        actions = torch.tensor(transition_dict['actions'],\n",
    "                               dtype=torch.float).view(-1, 1).to(device)\n",
    "        rewards = torch.tensor(transition_dict['rewards'],\n",
    "                               dtype=torch.float).view(-1, 1).to(device)\n",
    "        next_states = torch.tensor(transition_dict['next_states'],\n",
    "                                   dtype=torch.float).to(device)\n",
    "        dones = torch.tensor(transition_dict['dones'],\n",
    "                             dtype=torch.float).view(-1, 1).to(device)\n",
    "        rewards = (rewards + 8.0) / 8.0  # 对倒立摆环境的奖励进行重塑\n",
    "\n",
    "        ## self.actor(states) 是输出下一个状态的动作，以及熵的相反数\n",
    "        next_actions, log_prob = self.actor(next_states)\n",
    "        entropy = -log_prob   ##  熵\n",
    "        q1_value = self.target_critic_1(next_states, next_actions)        ##  目标价值网络的下个状态的价值输出\n",
    "        q2_value = self.target_critic_2(next_states, next_actions)\n",
    "        next_value = torch.min(q1_value,   ## 拿到最小的价值输出，然后加上熵，就是目标的下个状态的价值\n",
    "                               q2_value) + self.log_alpha.exp() * entropy\n",
    "        ## 目标当前状态的价值，时序差分的公式\n",
    "        td_target = rewards + self.gamma * next_value * (1 - dones)\n",
    "        ## 直接求出当前（状态、动作）的动作价值，和 间接求出的动作价值，使用 MSE 来算损失函数的，q_targets不反向传播求梯度\n",
    "        critic_1_loss = torch.mean(\n",
    "            F.mse_loss(self.critic_1(states, actions), td_target.detach()))\n",
    "        critic_2_loss = torch.mean(\n",
    "            F.mse_loss(self.critic_2(states, actions), td_target.detach()))\n",
    "\n",
    "        # 以上与SAC相同,以下Q网络更新是CQL的额外部分\n",
    "        '''\n",
    "        考虑一般情况，希望Q在某个特定分布μ(s,a)上的期望值最小，也就是约束Q，最小化Q，减小Q的取值\n",
    "        因特定分布并没有要求，所以什么样的分布都可以，下面的program指定了三类分布的\n",
    "        1、动作是均匀分布的\n",
    "        2、智能体策略网络给出采样的当前的状态的动作分布\n",
    "        3、智能体策略网络给出采样的下一个状态的动作分布\n",
    "        \n",
    "        所以价值网络的输入 状态都是使用当前的，动作来自不同的分布（均匀分布的、策略网络给出当前状态的动作，策略网络给出下一个状态的动作）\n",
    "\n",
    "        这三类不同的分布上，都要满足约束条件，也就是损失函数，达到减小价值Q的目的，而且\n",
    "        \n",
    "        q1_unif   价值1网络求出（当前的状态、均匀分布的动作）的动作价值\n",
    "        q2_unif   价值2网络求出（当前的状态、均匀分布的动作）的动作价值\n",
    "        q1_curr   价值1网络求出（当前的状态、策略网络给出的当前的动作）的动作价值\n",
    "        q2_curr   价值2网络求出（当前的状态、策略网络给出的当前的动作）的动作价值\n",
    "        q1_next   价值1网络求出（当前的状态、策略网络给出的下一个状态的动作）的动作价值\n",
    "        q2_next   价值2网络求出（当前的状态、策略网络给出的下一个状态的动作）的动作价值\n",
    "\n",
    "        实际任何动作分布都可以的，但是作者只使用了这三类(s,a)分布的，\n",
    "        '''\n",
    "        batch_size = states.shape[0]  ## 32*2\n",
    "        ##  torch.rand 先随机生成数据，然后 uniform_均匀分布来填充tensor (-1, 1)，前一个 rand 其实只是初始化了tensor\n",
    "        random_unif_actions = torch.rand(   ## (320, 1)\n",
    "            [batch_size * self.num_random, actions.shape[-1]],\n",
    "            dtype=torch.float).uniform_(-1, 1).to(device)\n",
    "        random_unif_log_pi = np.log(0.5**next_actions.shape[-1])  ## 自定义的熵的相反数，和动作的个数相关，个数越少熵越小\n",
    "        tmp_states = states.unsqueeze(1).repeat(1, self.num_random,     ## 多次重复当前的状态，最后reshape到2dim，和 states 的 dim 相同的  (320, 3)\n",
    "                                                1).view(-1, states.shape[-1])\n",
    "        tmp_next_states = next_states.unsqueeze(1).repeat(              ## 多次重复下一步状态，最后reshape到2dim，和 next_states 的 dim 相同的  (320, 3)\n",
    "            1, self.num_random, 1).view(-1, next_states.shape[-1]) \n",
    "        random_curr_actions, random_curr_log_pi = self.actor(tmp_states)  ## 策略网络输出当前状态的动作，以及熵的相反数 (320, 1) (320, 1)\n",
    "        random_next_actions, random_next_log_pi = self.actor(tmp_next_states) ## 策略网络输出下一个状态的动作，以及下一个熵的相反数 (320, 1) (320, 1)\n",
    "        q1_unif = self.critic_1(tmp_states, random_unif_actions).view(    ## 价值1网络求出（当前的状态、均匀分布的动作）的动作价值   [64, 5, 1]\n",
    "            -1, self.num_random, 1)\n",
    "        q2_unif = self.critic_2(tmp_states, random_unif_actions).view(    ## 价值2网络求出（当前的状态、均匀分布的动作）的动作价值   [64, 5, 1] \n",
    "            -1, self.num_random, 1)\n",
    "        q1_curr = self.critic_1(tmp_states, random_curr_actions).view(    ## 价值1网络求出（当前的状态、策略网络给出的当前的动作）的动作价值   [64, 5, 1]\n",
    "            -1, self.num_random, 1)\n",
    "        q2_curr = self.critic_2(tmp_states, random_curr_actions).view(    ## 价值2网络求出（当前的状态、策略网络给出的当前的动作）的动作价值   [64, 5, 1]\n",
    "            -1, self.num_random, 1)\n",
    "        q1_next = self.critic_1(tmp_states, random_next_actions).view(    ## 价值1网络求出（当前的状态、策略网络给出的下一个状态的动作）的动作价值   [64, 5, 1]\n",
    "            -1, self.num_random, 1)\n",
    "        q2_next = self.critic_2(tmp_states, random_next_actions).view(    ## 价值2网络求出（当前的状态、策略网络给出的下一个状态的动作）的动作价值   [64, 5, 1]\n",
    "            -1, self.num_random, 1)\n",
    "        q1_cat = torch.cat([              ## [64, 15, 1]\n",
    "            ## 价值和熵相加，和动作的个数相关，个数越少熵越小\n",
    "            q1_unif - random_unif_log_pi,\n",
    "            q1_curr - random_curr_log_pi.detach().view(-1, self.num_random, 1),   ## 价值和熵相加\n",
    "            q1_next - random_next_log_pi.detach().view(-1, self.num_random, 1)    ## 价值和熵相加\n",
    "        ],\n",
    "                           dim=1)\n",
    "        q2_cat = torch.cat([                              ## [64, 15, 1]\n",
    "            q2_unif - random_unif_log_pi,\n",
    "            q2_curr - random_curr_log_pi.detach().view(-1, self.num_random, 1),   ## 价值和熵相加\n",
    "            q2_next - random_next_log_pi.detach().view(-1, self.num_random, 1)    ## 价值和熵相加\n",
    "        ],\n",
    "                           dim=1)\n",
    "        ## https://pytorch.org/docs/stable/generated/torch.logsumexp.html?highlight=logsumexp#torch.logsumexp\n",
    "        ## 在用户指定的 dim 上，求exp，然后累加的，最后求log\n",
    "        ## 迭代方程的第一个因子\n",
    "        qf1_loss_1 = torch.logsumexp(q1_cat, dim=1).mean()\n",
    "        qf2_loss_1 = torch.logsumexp(q2_cat, dim=1).mean()\n",
    "        qf1_loss_2 = self.critic_1(states, actions).mean()  ## 返回历史真实数据的状态动作对的价值\n",
    "        qf2_loss_2 = self.critic_2(states, actions).mean()  ## 返回历史真实数据的状态动作对的价值\n",
    "        qf1_loss = critic_1_loss + self.beta * (qf1_loss_1 - qf1_loss_2) ## qf1_loss_2加了负号就是最大化，qf1_loss_1和critic_1_loss最小化\n",
    "        qf2_loss = critic_2_loss + self.beta * (qf2_loss_1 - qf2_loss_2) ## qf2_loss_2加了负号就是最大化，qf2_loss_1和critic_2_loss最小化\n",
    "\n",
    "        self.critic_1_optimizer.zero_grad()     ## 价值网络的参数梯度置零的\n",
    "        qf1_loss.backward(retain_graph=True)    ## 价值网络的损失loss反向传播梯度\n",
    "        self.critic_1_optimizer.step()          ## update 网络\n",
    "        self.critic_2_optimizer.zero_grad()\n",
    "        qf2_loss.backward(retain_graph=True)\n",
    "        self.critic_2_optimizer.step()\n",
    "\n",
    "        # 更新策略网络\n",
    "        ## self.actor(states) 是输出当前状态的动作，以及熵的相反数\n",
    "        new_actions, log_prob = self.actor(states)\n",
    "        entropy = -log_prob  ## 熵\n",
    "        ## 此时的动作价值网络已经 update 了的\n",
    "        q1_value = self.critic_1(states, new_actions)\n",
    "        q2_value = self.critic_2(states, new_actions)\n",
    "        ## update以后的动作价值网络，使用当前的（状态、动作）的动作价值，加了负号的，也就是最大化动作价值的\n",
    "        actor_loss = torch.mean(-self.log_alpha.exp() * entropy -\n",
    "                                torch.min(q1_value, q2_value))\n",
    "        self.actor_optimizer.zero_grad()\n",
    "        actor_loss.backward()\n",
    "        self.actor_optimizer.step()\n",
    "\n",
    "        # 更新alpha值\n",
    "        alpha_loss = torch.mean(\n",
    "            (entropy - self.target_entropy).detach() * self.log_alpha.exp())\n",
    "        self.log_alpha_optimizer.zero_grad()\n",
    "        alpha_loss.backward()\n",
    "        self.log_alpha_optimizer.step()\n",
    "\n",
    "        self.soft_update(self.critic_1, self.target_critic_1)\n",
    "        self.soft_update(self.critic_2, self.target_critic_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "executionInfo": {
     "elapsed": 29772,
     "status": "ok",
     "timestamp": 1649958422630,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "HZ-ZGMjpGGAW",
    "outputId": "e393d353-cf32-4750-da0a-a31a60273bdf"
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'random' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[1], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mrandom\u001b[49m\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;241m0\u001b[39m)               \u001b[38;5;66;03m## 配置随机种子方便复现的\u001b[39;00m\n\u001b[0;32m      2\u001b[0m np\u001b[38;5;241m.\u001b[39mrandom\u001b[38;5;241m.\u001b[39mseed(\u001b[38;5;241m0\u001b[39m)\n\u001b[0;32m      3\u001b[0m _ \u001b[38;5;241m=\u001b[39m env\u001b[38;5;241m.\u001b[39mreset(seed\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0\u001b[39m)\n",
      "\u001b[1;31mNameError\u001b[0m: name 'random' is not defined"
     ]
    }
   ],
   "source": [
    "random.seed(0)               ## 配置随机种子方便复现的\n",
    "np.random.seed(0)\n",
    "_ = env.reset(seed=0)\n",
    "torch.manual_seed(0)\n",
    "\n",
    "beta = 5.0\n",
    "num_random = 5\n",
    "num_epochs = 100\n",
    "num_trains_per_epoch = 500\n",
    "\n",
    "agent = CQL(state_dim, hidden_dim, action_dim, action_bound, actor_lr,         ## 实例化 CQL\n",
    "            critic_lr, alpha_lr, target_entropy, tau, gamma, device, beta,\n",
    "            num_random)\n",
    "\n",
    "return_list = []\n",
    "allimage = []\n",
    "for i in range(10):\n",
    "    with tqdm(total=int(num_epochs / 10), desc='Iteration %d' % i) as pbar:\n",
    "        for i_epoch in range(int(num_epochs / 10)):\n",
    "            # 此处与环境交互只是为了评估策略,最后作图用,不会用于训练\n",
    "            epoch_return = 0\n",
    "            state = env.reset()\n",
    "            if len(state)!=2*2-1:\n",
    "                state = state[0]\n",
    "            done = False\n",
    "            while not done:\n",
    "                if i==9:\n",
    "                    img = env.render()\n",
    "                    allimage.append(img)\n",
    "                action = agent.take_action(state)\n",
    "                next_state, reward, done, _ = env.step(action)\n",
    "                state = next_state\n",
    "                epoch_return += reward\n",
    "            return_list.append(epoch_return)\n",
    "\n",
    "            for _ in range(num_trains_per_epoch):\n",
    "                ## 从SAC在train时保存的历史数据采样，用来 train CQL\n",
    "                b_s, b_a, b_r, b_ns, b_d = replay_buffer.sample(batch_size)\n",
    "                transition_dict = {\n",
    "                    'states': b_s,\n",
    "                    'actions': b_a,\n",
    "                    'next_states': b_ns,\n",
    "                    'rewards': b_r,\n",
    "                    'dones': b_d\n",
    "                }\n",
    "                agent.update(transition_dict)  ## train CQL\n",
    "\n",
    "            if (i_epoch + 1) % 10 == 0:\n",
    "                pbar.set_postfix({\n",
    "                    'epoch':\n",
    "                    '%d' % (num_epochs / 10 * i + i_epoch + 1),\n",
    "                    'return':\n",
    "                    '%.3f' % np.mean(return_list[-10:])\n",
    "                })\n",
    "            pbar.update(1)\n",
    "    if i==9:\n",
    "        # https://github.com/guicalare/Img2gif/blob/master/Code/Img2Gif.py\n",
    "        imageio.mimsave(os.path.join(pth, 'chapter%s.gif'%str(num)), allimage, duration=10)\n",
    "\n",
    "# Iteration 0: 100%|██████████| 10/10 [01:34<00:00,  9.42s/it, epoch=10,\n",
    "# return=-904.511]\n",
    "# Iteration 1: 100%|██████████| 10/10 [01:33<00:00,  9.37s/it, epoch=20,\n",
    "# return=-450.740]\n",
    "# Iteration 2: 100%|██████████| 10/10 [01:31<00:00,  9.15s/it, epoch=30,\n",
    "# return=-913.236]\n",
    "# Iteration 3: 100%|██████████| 10/10 [01:22<00:00,  8.29s/it, epoch=40,\n",
    "# return=-658.278]\n",
    "# Iteration 4: 100%|██████████| 10/10 [01:22<00:00,  8.22s/it, epoch=50,\n",
    "# return=-236.583]\n",
    "# Iteration 5: 100%|██████████| 10/10 [01:22<00:00,  8.20s/it, epoch=60,\n",
    "# return=-325.743]\n",
    "# Iteration 6: 100%|██████████| 10/10 [01:22<00:00,  8.21s/it, epoch=70,\n",
    "# return=-211.936]\n",
    "# Iteration 7: 100%|██████████| 10/10 [01:22<00:00,  8.23s/it, epoch=80,\n",
    "# return=-182.652]\n",
    "# Iteration 8: 100%|██████████| 10/10 [01:22<00:00,  8.27s/it, epoch=90,\n",
    "# return=-226.983]\n",
    "# Iteration 9: 100%|██████████| 10/10 [01:22<00:00,  8.25s/it, epoch=100,\n",
    "# return=-349.087]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 573
    },
    "executionInfo": {
     "elapsed": 3,
     "status": "ok",
     "timestamp": 1649958422631,
     "user": {
      "displayName": "Sam Lu",
      "userId": "15789059763790170725"
     },
     "user_tz": -480
    },
    "id": "thlib0emGGAY",
    "outputId": "3b24eb59-cd5a-4000-8ba3-a4b012da38dd"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEWCAYAAACjYXoKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3dd3hc1bXw4d9S73KRbMtyx3I32Eb0DqYHDAQSSgIhhZBAQpKb3EDId4GQRgokhHJD6CSBcAk1FIPBYJrBFVvucpXkot5GfWZ9f5wzYiyrj2ZGZb3PM49n9mn7+NizZndRVYwxxphgREU6A8YYYwY+CybGGGOCZsHEGGNM0CyYGGOMCZoFE2OMMUGzYGKMMSZoFkyMMcYEzYKJMQOciOwSkYV9va8xPWHBxPR7InKliKwUkVoR2Scir4vIiQHbZ4nIyyJSJSI1IvKOiBwbsH2SiKiIxIQ537tEpN7N9wEReVxEUsKZh/7KfSZLRaRORDZbgBv4LJiYfk1EfgT8Cfg1MBqYADwALHK3HwZ8CKwHJgNjgReBt0Tk6EjkuY0LVDUFWADkAj+PcH76i6eBNcBI4FbgORHJjGyWTDAsmJh+S0TSgV8AN6jq86rqUdVmVX1FVX/i7nY78LGq3qqq5apao6r3An8H7urNNUXkSREpEZHdIvJzEYlyt31NRD4QkT+ISIWI7BSRc7tzXlUtAl4H5rjnOlZEPhKRShH5TERODcjDuyJyp4h86Ja03hSRjIDtX3XzViYit7bJ/+Mi8suAz6eKSGEH99rpvm7J6icisk5EPCLyiIiMdkuGNSKyRESGd3Du10XkxjZpn4nIJSIyDSe43qaq9ar6b5wfA1/sxl+l6acsmJj+7DggAXihk33OBP6vnfRngZNEJKGH1/wLkA5MAU4BrgauDdh+DLAFyAB+BzwiItLVSUVkPHAesEZEsoFXgV8CI4AfA/9u88v8Sve6o4A4dx9EZBbwIPBVnFLYSGBcD++xJ76I83c8DbgAJyD+DMjE+f74fgfHPQ1c4f/g5nsizn3PBnaoak3A/p+56WaAsmBi+rORQKmqtnSyTwawr530fUA0zpd1t4hINHA5cItbwtkF/BHni9tvt6r+TVW9wBNAFk71W0deFJFK4APgPZzquq8Ar6nqa6rqU9W3gJU4wcbvMVXdqqr1OIFxnpt+KfAfVV2mqo3A/wN83b3HXviLqh5wS1bvA5+o6hpVbcAJ8vM7OO4FYJ6ITHQ/XwU87+Y5Bahqs38VkNr32TfhYsHE9GdlQEYXDeelOF/obWUB6p6juzKAWGB3QNpuIDvg837/G1Wtc9921qh+kaoOU9WJqvpdNzhMBC5zq7gq3WBzYpv72B/wvi7gGmOBgoA8eOjZPfbUgYD39e18TgEQkf91OxrUisjP3FLHqzjBGZxSyj/c97VAWpvrpAE1mAHLgonpzz4GGoGLOtlnCXBZO+lfApa7v4S7qxRoxvmy95sAFPXgHN1RADzlBhn/K1lVf9uNY/cB4/0fRCQJpwTn5wGSAj6P6eRcPdm3U6p6vaqmuK9fu8lPA1eIiL+6cqmbvgGYIiKBJZEj3HQzQFkwMf2WqlYB/wPcLyIXiUiSiMSKyLki8jt3tzuA40XkVyIyQkRSReR7OO0N/9PmlPEikhDwOujfv1t19SzwK/c8E4Ef4TTm96W/AxeIyNkiEu3m5VQR6U7bx3PAF0TkRBGJw+mgEHgfa4Hz3L+LMcAPOjlXT/btjddwAvMvgH+pqg9AVbe6177NvfeLgcOBf/fx9U0YWTAx/Zqq/hHnC/3nQAnOr/obcbr/oqrbcKqIjgB2AZXAncDFqrqkzelqcapm/K/T27nk93B+se/Aaef4J/BoH99TAU7X5p8F3NNP6Mb/R1XdANzg5msfUAEE9tZ6CqcxexfwJvCvTk7Xk317zC0VPg8sdPMb6HKcrtIVwG+BS1W1pC+vb8JLbKVFM5i4v+6X43Q7fSTS+TFmqLCSiRlUVLUQOBfIstHmxoSPlUyMMcYEzUomxhhjghbWie/6k4yMDJ00aVKks2GMMQPKqlWrSlX1kHnUhmwwmTRpEitXrox0NowxZkARkd3tpVs1lzHGmKBZMDHGGBM0CybGGGOCZsHEGGNM0CyYGGOMCZoFE2OMMUGzYGKMMSZoFkyMMSZC6pu8/H35bvKLayOdlaAN2UGLxoSLqrKtuJaahha8PiU6Spg3fhjRUV0uHW8GKa9P+ffqQv745hYOVDeSFBfNby6Zy6J52V0f3E9ZMDEmhFq8Pn7+Yh7PrCg4KH366FRuPncGp07PRMSCymBUVdfMPUu2UlLTSH2zl4ZmL81eH81epbS2kcKKeo4YP4xfXjSXvy3bwU3PrGXlrgquPm4izV6lxedjSmYKKfED42t6yM4anJubqzadigmluqYWbvznGt7ZXMx1J0/hhKkZRIuwv7qBv7yzjd1ldRw7ZQS3XTCbmVltl0Q3feXdLcXMGpvGqNSEsF73xn+u5vW8/UzOSCYhNoqEmGhio6OIiRbiY6K5cN5YLjg8CxGh2evj94u38NCyHQedY2RyHD85ezqX5Y7vNyVZEVmlqrmHpPe3YCIivwcuAJqA7cC1qlrpbrsF+AbgBb6vqovd9HOAPwPRwMPdWUvbgokJpaq6Zq5+9BPWF1Vx50VzuOqYiQdtb2rx8cyKPfxpyTaq6pv5xomT+cHCHJLiBsav0IFi+Y4yLn9oOSdPy+TJrx8dtuu+tLaIm55Zy0/Ons4Np03t9nGr91RQVFFPbHQUPlUe/WAnK3dXMCc7jYvmZdPsVZq9PnInDef4wzJCeAcdG0jB5CzgHVVtEZG7AFT1pyIyC3gaOBoYCywBprmHbQXOxFm+dAVwhapu7Ow6FkxMKN395hb+sjSfv37lSM6aPabD/Srrmvjt65t5ZkUBY9MTOGryCBJiokmMi2bRvLHMnzA8jLkeXJq9Ps6/933yi2vxKfz7O8dz5MS+//tcsvEA9yzZytdPmMzF87MprmnkrHve47BRKfzft48jJrr3/ZxUlZc/28tvXtvM/uqG1vSYKOGxa4/ipJxDJu8NuQETTAKJyMU4a0Nf5ZZKUNXfuNsWA7e7u96uqme76Qft1xELJiZUWrw+TrjrHWZmpfH4td37NbxyVzm/X7yF/dUNNDR7qapvptmr3HRGDjecNrVfVHGoasTbd7w+ZeWuchZMHE5swJd0i9fHe1tLOGryCNISYgF4+P0d/PLVTfz58nnc8cpG5mSnd6t08kbefqrqm/jyURO63HfbgRouuv9DvKo0NPuYk51GQkw0G/ZW89pNJzE5I7n3NxugxevD0+glNkZoavFx+UPLKayo5/+uPy7sVaQdBZP+Xqb+OvAv9302ztrefoVuGkBBm/Rj2juZiFwHXAcwYULX/1CM6Y13t5RwoLqROy7s/r+x3Ekj+Ne3j2v9XN3QzP97MY+739rK+9tKuPKYCQiCCJyUk8mI5LhQZL1Dm/dX8/XHVvCdUw/jq8dNCuu1/VSVW55fx7MrCzksM5mff2EWp00fxUf5pdz+yga2HqhlTFoCv7p4DrPHpnPPW1s5fcYoLjxiLPurGvjN65tZvaeCBZ2U9t7aeIDv/mMVPoWxwxI7/eVf3dDMt59aRWJcNC/feCKf7iznrjc2s6+qgTsvmtNngQQgJjqK9CQneCbFwWPXHsXF93/EtY+t4IUbjicrPbHPrtVbESmZiMgSoL2y/62q+pK7z61ALnCJqqqI3AcsV9W/u9sfAV53jztHVb/ppn8VOEZVb+wsD1YyMaHyjcdX8FlhFR/fcvpBv55744U1hfy/FzdQ29jSmjZjTCqvfv+ksJVWSmsbWXTfhxRV1hMl8OjXjuLU6aMA8PmUV9fvY29lPdFRQnSU05jsafRS1+TkOTEuhqS4aI6bMpIjxg/rdT5+8/om/vreDi49chyrdlews9TDYZnJbC/xMG54ItedPIV/LN/DlgM1ZKUnUOZp4q0fnszEkcnUNbVw4l1LmZudzuPXHsXrefu59+1tDEuK5efnz2JOdjqr91Rw5d+WM210KnVNXmoamln8g5MZlvR54G5s8eL/yrzxn6t5d0sJ//jmMRwzZSTgjBtZV1jJ0ZNHhLwUt3FvNV/668dkD0vkn986hpEp8SG9nl+/Kpmo6sLOtovI14AvAGfo59GuCBgfsNs4N41O0o0Jq31V9SzdUsz1pxwWdCABuHj+OM6YOZqy2ibAaVC+5fn1PLeqoFvVMMFqbPFy/VOrKPM08sx1x/KLVzbyvX+u4fnvHk9qQiw/ee4z3t9W2u6xibHRANQ3ewGIi4niqa8f3frF2xMPLdvOX9/bwVeOncCdi+bQ7FWe/HgXz60q5L/OnMa3Tp5CQmw0lx81gQfezef+pfncdEYOE0c6pYOkuBiuO3kKv319M+fd+wGb9lUzdVQK2w7UcsF9H3DpgnG8vbmY0WkJPPq1o9hf1cBF93/Iz15Yz/1XLmDLgRp++Z9NfJB/8L3eceHsg+4nMS66V/fXG7PGpvHQV4/k2sdXcNXDn/DPbx0b9hJroH7XZuL2zLobOEVVSwLSZwP/5PMG+LeBHEBwGuDPwAkiK4ArVXVDZ9exkokJhT8v2cY9S7by3k9Obf0i60uqyqX/+zF7yut498enkhzCMQhen/LTf6/juVWF3HflfL5w+Fj2VtZz4X0fEhct1Da20OxVbj1/JhfPz8ariterxMVEkRgbTZRbcvL5nHEVV/xtOcU1jTz7baeev9nr4/nVhRRVNnD1cRPJcH9Ze33KsysL+PeqQsrrmqiqa6bM08T5h2dx7+Xzu1Ui8zS2kBQXfVDpwNPYwml/eJcoEX505jS+eOQ4ahtb+POSbTzx8S7SE2N5/jvHM8mtnnrg3Xx+98YWTp6WyQfbSkhNiOWqYyaQkuD8nY8bntTatTeSPthWyjeeWMGUzBT++c1jGB7igDJgGuBFJB+IB8rcpOWqer277VacdpQW4Aeq+rqbfh7wJ5yuwY+q6q+6uo4FE9PXvD7l5N8tZXJGMn//ZrvNdn1i9Z4KLnngI75/+lR+dNb0kFzjkx1l/OI/G9mwt5qbzsjhh2dOa922Zk8FV/xtOTOz0rj7S/O63TZQVFnPFx/4CJ8q3zsjh0fe38GusjoAUuJjuP6UKcyfMJxfv7aJDXurmZWVxuSMZNKTYpkwIolrT5hEfEx0UPdVVd9MfEwUCbEHn2d3mYfoKGHc8KTWNK9PueJvy1m1u4KvHDOBHyycFvIv6t5atrWEbz65kllZabzw3eNDGuAGTDAJFwsmpq+9u6WYrz22ovVXfCh97+k1vLVxP0t/fGqfNr7WNDRz87/X8+r6fYxNT+Dm82a2++u7qq6ZlISYHrfbbD1Qw6UPfkR1QwszxqTyk7OnM3FkMr97YzNvbjwAQFZ6Aj87byZf6Ae/+uuaWqisa2bssMg3cHfl78t38/MX83jhu8eHtEu5BZM2LJiYvvbNJ1awtqCSD28+Pehf0F0pKK/jjLvfY/74Yfz+0iOYMDKp64O6oKrc+PQa3sjbz/dPz+G6k6eQGNf397Flfw27yzwsnDm6tSoMnO7RWw/UctH8sTZ4sxdqGprJ/eUSvpQ7njsvmtOaXlXXzEfbSzl3blafXKejYGKzBhvTBwrK63h7czGXHzUh5IEEYPyIJH65aA7ri6pYeM97/H7xZvZV1VNQXkd+cS2b91eTX1zDjpJaquqbu3XOv3+yh1fX7ePHZ03npoU5IQkkANPHpHLW7DEHBRJwukdfecwECyS9lJoQy9mzx/DKur00tnhb0+98dSPf+cdqdpd5Qnp9e2rG9IG/f7KbKBGuPCZ845e+dNR4Tp6WyV1vbOb+pdu5f+n2dvdLiI3iR2dO4+snTO5wNHZeURV3vrKR06Zn8u2Tp4Qy2yaELlmQzcuf7WXp5hLOmTOG/OJanl9dCEBeUXVIOoX4WTAxphse+WAn720t4QcLcw4Z9NbQ7OVfKwo4c+bosNetj0lP4J4vz+Nrx09iXWEl8bHRJMRGExMleH2K1x0H8uvXNvPS2r389zkziIuOwtPYgqephfomL/XNXh7/aBcjU+L445fmHVJiMAPHiVMzyEyN5/nVhZwzZwx/WrKVhNhomlp85O2t4vzD+6aqqz0WTIzpgqryt2U72F/dwLKtJXzh8Cx+es4Mxo9w2ile+WwvlXXNXH38xC7OFDpHjB/W4YDARfPG8kbefv7n5Q1c8+in7e6TEh/D49ceFdFxCiZ4MdFRXDRvLI9/tIsP80v5z7p93HjaVN7ZXExeUVVorx3SsxszCKwvqmJ/dQN3LppNSW0TDy3bzpsbDvDNkyZzw2lTefLj3eSMSuG4MA1W6ykR4dy5WRw/NYOVu8pJjIsmNT6WpPhoEt2STHJ8dFjaekzoXbJgHH97fyfXP7WKtIQYvnXyFIprGliyqTik86tZMDGmC29uOEB0lPCFw8cyPDmOK4+ewF1vbOaBd7fzzIoCyj1N3LlodsS7sXYlPTGWM2aOjnQ2TIjNzEpjZlYam/ZV8+OzppGeGMvc7HSeXVnIvqqGkFXFWm8uY7rw1sYD5E4c3jpgzd9O8e/vHM+44YlkpMRz8YJxEc6lMZ/7xomTmT46lWtPmAzA7Ox0gJBWdVnJZIjIL67h5bV7nSkvfDBxZBJXHG0zJ3dlT1kdWw7U8PPzZx6y7ciJw3nphhNo8vqsisj0K5ceOY5Lj/z8B87MMWlECeTtre50fZ1gWDAZIu57J58X1+4lOkoQoMWnTBudGpLFggaTNzfuB+CsWe3/BxQRCySm30uMi2bqqBQ2hLBkYtVcQ8S24lpOmZbJ9l+fx7rbzyIjJY6739oS6Wz1e29uPMCMMal9MsLcmEiaMzad9RZMTDB8PmV7SS1TR6UAznTc3zl1Kh/ml/HR9vanDzdQ7mli5a5yzpxljdZm4JudnU5xTSPFAcv/9iULJkNAUWU9Dc0+ctxgAnDVMRMYk5bA3W9uZajOz9aVdzYX41MsmJhBYa7bCL9hb3VIzm/BZBD40bNr+dGza/H52g8K+cW1AK0lE4CE2GhuOH0qK3dX8N7WknaPG+oWb9jPmLSE1v+Exgxks8Y6a8WHqkeXBZNB4J3NxTy/uojfvrG53e3bimuAg4MJwJdzx5M9LJG737LSSVslNY0s3VzMBUdEfhp0Y/pCSnwMUzKSyds7xIKJiPyXiKiIZLifRUTuFZF8EVknIgsC9r1GRLa5r2sil+vwq6xrorKumaz0BB5atoOnlu8+ZJ/84loyUuIPWssanGVUv3HiZNYVVlFYUR+uLA8IL6wppMWnfPmo8V3vbMwAMTs7nbyiIVTNJSLjgbOAPQHJ5+Is05sDXAc86O47ArgNOAZnSd/bRGTI9HfdWepMK337hbM5fcYobnspj6Vbig/aJ7+4lqmj2p8t9IjxThXOlv01oc3oAKKq/GtFAQsmDGPqqNRIZ8eYPjNnbBpFlfVUeJr6/Nz9MpgA9wD/DQTWvSwCnlTHcmCYiGQBZwNvqWq5qlYAbwHnhD3HEeIPJodlpvCXK+YzdVQKv3ltU+t2VWVbce0hVVx+00Y7X5ZbDlgw8Vu9p4LtJR4rlZhBZ/6E4Rw7ZQSV3Vzjpif6XTARkUVAkap+1mZTNlAQ8LnQTesovb1zXyciK0VkZUnJ4Gh03lXqIUpgwogkkuNjuOzI8Ww9UMveSqfaqqSmkZqGFqZmth9MUhNiGTc8kU37QlP0HYj+taKA5LjokC+9a0y4HT15BM9cdxyTM/p+XZOIBBMRWSIiee28FgE/A/4nFNdV1YdUNVdVczMzM0NxibDbWVZH9vBE4mKcR3nKdOe+lrk9tPw9uXJGd1xdM2NMmlVzuWobW/jPun184fCxJMfbBBHGdFdEgomqLlTVOW1fwA5gMvCZiOwCxgGrRWQMUAQE1juMc9M6Sh8SdpV6mBSwelrOqBSy0hNau/vmlxzaLbitGWNS2VHqOWipz6Hq1XV7qWvy8iWr4jKmR/pVNZeqrlfVUao6SVUn4VRZLVDV/cDLwNVur65jgSpV3QcsBs4SkeFuw/tZbtqgp6rsKvUcVGQVEU6ZlskH20pp9vrYdqCW1PgYRqXGd3ieGVmpeH3aWooZyl5YU8TUUSksmND+QlPGmPb1q2DShddwSi75wN+A7wKoajlwJ7DCff3CTRv0yjxN1DS2HFQyAThlWiY1jS2sLah0enKNTul0rMSMMU4V2OZ9Q7uqS1XZuLeaY6eMsLElxvRQv64Udksn/vcK3NDBfo8Cj4YpW/3GLrcnV9vGtOOnZhAdJby3pYT8klpOndZ5+9CkkcnExUQN+R5dFXXNVDe0MDmj4ypBY0z7BlLJxLTh7xY8qU0wSU+MZcGEYfxn3V5Kaho7bS8BZ93onFEpbB7ijfA7S51qvikh6OlizGBnwWQA21XmITpKGDf80GU4T5mWya6yOqDzxne/6WNS2TzEuwfvKGm/pGeM6ZoFkwFsV2kd44cnEht96GM8OaBqK6cbo7hnjkmjuKaR8hCMjB0odpZ6iOkgOBtjOmfBZADbWeo5pIrLb87YdEYkxxEfE0V2N74cp/sb4fcP3dLJzlIPE0YmEdNOcDbGdM7+1wxQqsquMs8hPbn8oqKERfPGctxhI4mO6rpn0owsd1qVIdxusrPUY+0lxvRSv+7NZTpWUtNIXZO30/r92y6Y3e3zZabEMyI5bsgGE5/PCc4nTs2IdFaMGZCsZDJAddSTq7dEhOmjU9k0RIPJ/uoGGpp9TM60kokxvWHBZIDaVeb2POqgmqs3ZmSlsnV/TYcrNg5mOzsYs2OM6R4LJgPIR/mlrdVQO0vriI0Wxg5L6LPzzxiTSn2zl4KKuj4750Cxww0mU2zAojG9Ym0mA0RTi49rHvsUr7v63+6yOsaP6NueR1Pcaep3lHqY2IclnoFgZ4mHxNhoRqd1PIeZMaZjVjIZIHaVeWj2KkdOHM7/rSzko+1lfVrFBZ9X8ex0B+8NJTtLa5mckWxzchnTS1YyGSC2uzP63nbBbJLiorl/6XbOnDW6T68xMjmO1ISY1vaDoWRnqYfZ2emRzoYxA5YFkwHCPz38lMxkkuJi+OOXjujza4gIUzKSh1wwaWrxUVBRbysrGhMEq+YaIPJLaskelkhSXGjj/+QhGEwKKurw+tR6chkTBAsmA8T2kloO68aEjcGanJFCUWU9Dc1DZ9XF1qn8bYyJMb1mwWQA8PmU7cUeDgvDl53/C9U/jiVcXv5sL799fXNYr+m3s7VbsAUTY3qrXwYTEfmeiGwWkQ0i8ruA9FtEJF9EtojI2QHp57hp+SJyc2RyHTp7q+qpb/Z2ayr5YE2JUI+u51YV8vD7O6hvCn+JaEeph+FJsQxLigv7tY0ZLPpdA7yInAYsAo5Q1UYRGeWmzwIuB2YDY4ElIjLNPex+4EycNeNXiMjLqrox/LkPje3uF/vUzHBUcznBZEeY2012ltbS4lPy9lZx1KQR4b12icfaS4wJUn8smXwH+K2qNgKoarGbvgh4RlUbVXUnzlrwR7uvfFXdoapNwDPuvoOGvydXOEomyfExjE6LD2sjfGOLl8KKegDW7KkI23XBmX15W3GtLdVrTJD6YzCZBpwkIp+IyHsicpSbng0UBOxX6KZ1lH4IEblORFaKyMqSkpIQZD008otrGZYUy4jk8FTDhLtH156yOtSdDmz17so+O2+z18cD7+azqZMVJIsq6ymtbeSI8TbGxJhgRCSYiMgSEclr57UIp+ptBHAs8BPgWemjYcmq+pCq5qpqbmZmZtcH9BPbS2qZmpkSttHZkzNSwhpMdgRMsrh6TwWqfTPR5P++u53fvbGFRfd9yGMf7mz3vGsLnOA1f/zwPrmmMUNVRIKJqi5U1TntvF7CKVk8r45PAR+QARQB4wNOM85N6yh90NheXBuWKi6/KRnJlHuaqKwLzxK+/q65l8zPprimkX1VDUGfc8v+Gu59ZxtnzhrNSTkZ3PHKRr7++Aqq6poP2m/NnkriY6JaFwczxvROf6zmehE4DcBtYI8DSoGXgctFJF5EJgM5wKfACiBHRCaLSBxOI/3LEcl5CFR4mijzNHFYGBrf/Vrn6ApT6WRnqYeMlDhOme6UFtfsCa6qq8Xr4yfPfUZaQiy/vWQuD1+Tyx0XzmbZtlIeeC//oH3X7Kng8HHpxNpSvcYEpT/+D3oUmCIieTiN6de4pZQNwLPARuAN4AZV9apqC3AjsBjYBDzr7jsobC8JX+O7n3+sSbiCyY5SpzfVjDFpxMdEBd0I/9D7O1hXWMUdi2YzMiUeEeGa4ydx3JSRLNl4oHW/xhYveXurmT/BqriMCVa/6xrs9sj6SgfbfgX8qp3014DXQpy1iAhnTy6/8cOTiI6SsJZMTpueSVxMFHOz01lT0PuSyYHqBv701jbOnTOG8+dmHbRt4cxR3P7KRna6wWvTvhqaWnzMHz8s2FswZsjrjyUTEyC/uJb4mCjGDksM2zXjYqIYPzwxLGNNahqaKalpbO2aO3/CMNYXVdHU4uvV+VbtrqDJ6+P6Uw47pMPCGTOdWZbf3uSUTvwlICuZGBM8Cyb93PaSWqZkphAdFd51NiZnJIdlFPyu0rrW64Hzxd7U4mNjJ915O5NXVEVMlDB9zKEN6uNHJDF9dCpLWoNJJVnpCYxJ77vVKo0ZqiyY9HP5JeHtyeXn7x7cV910O7KjtNa9nhNMFrilhN62m2zYW03O6FQSYqPb3X7GzFGs2FVBVV0zawoqmD/BqriM6QsWTPqxTfuqKayoJycSwSQzmfpmL79fvIW/vredpz/d0+uqp87sLPUgAhNHJgEwJj2BrPSEXvXoUlXyiqqYPTatw30WzhqN16c8t7qQgvJ6G19iTB/pdw3wxlHhaeK6p1YyOjWBK46eEPbr504cTkp8DA+8u701LTpK+FLu+E6O6rmdpR7GpiceVJKYP2EYq3tRMjlQ3UiZp4k5nQSTeeOGkZESx4Pv5rdeyxgTPCuZ9ENen/L9Z9ZwoKqRB7+ygMzU+LDnYWZWGnl3nM32X5/Hxl+czbjhiby2fl+fX2dXqYcpbabWP2rSCAor6ikorzsoffGG/WHDA8gAAB3+SURBVMz7xZuU1Ta2e64Ne6sAOl1+NypKOG36KEprm4iJEubYUr3G9AkLJv3Q7xZv5v1tpdx50eyI9zSKjhKS4mI4b24WH+aXHjKCPBiq2jrGJNCJUzMA+Gh76UHpL6/dS2Vdc2sDelt5RdWIOIGwM/5eXTOz0jpsWzHG9IwFk36kqcXHbS/l8df3dnDVMRP48lHhr97qyHlzs2j2Km918EXeG2WeJmoaWg4JJlNHpTAqNZ73t30eTFq8Pt7f5kzO+eaG9vOwYW8VkzOSSYnvvPb2pJwMEmOjyZ1k7SXG9BVrM+kniqsb+O4/VrNydwXfOmkyPz1nRqSzdJAjxqWTPcyp6rr0yHF9cs6dARM8BhIRTpyawbtbS/D5lKgoYU1BJdUNLUwcmcT7+aV4GltIbhM0NuytZsHErgNEcnwMr3zvBEalWZdgY/qKlUz6gQpPExfc9wEb9lZz7xXzufX8WcT0s7miRITz5o7h/W0lVNX3TVWXfxzLlHbWEjkxJ4NyTxOb9jvjTd7dUkx0lPCz82bS1PJ5KcWvwtNEUWV9p43vgaaOSiUtITbIOzDG+PWvb6whatm2Eg5UN/LINblceMTYSGenQ+e6VV2B81sFamj24vN1f1zKjlIPsdFC9vBDR/ef4LabfJjvVHW9u6WEIycM54wZoxiWFHtIVdeGvU7QmT3WGtSNiQQLJv3Ail3lpMTHcMyUkZHOSqfmjx/G2PSEdnt1NXt9nHjXUs798/ss3VLcrcGOO0pqmTAiqd3R/aPTEsgZlcIH+WUU1zSwYW81p0zPJCY6ijNmjObtzcU0ez8f95Ln78nVzZKJMaZvWTDpB1bsrGDBxOFhnzKlp0SEc+dm8f62UqobDq7q2l1WR2ltIwUVdVz72Aq+8sgnh3TtbWvD3upOe16dMDWDT3eW8ZZbEjrVnaL+rNmjqapvZsXO8tZ984qqyB6WyPAwrUZpjDmYBZMIq6xrYsuBGo4eID2Lzps7hiavj2VbD26z8M9u/NQ3jua2C2axenclf1qyrcPz+Ns45nYyzuOknAwamn08sHQ7manxzHIDz0k5GcTHRPFmQHXbxr3VVioxJoIsmETYyl3OSO+jJo2IcE66Z272MGKjhbyigydizC+uAWD6mDSuPWEyx04ZQV5RVYfnWe9u6yyYHDNlJNFRQlFlPadMy2ydBTgpLoaTcjJ5a+MB8otr2F5Sy45Sjw1ANCaC+l0wEZF5IrJcRNaKyEoROdpNFxG5V0TyRWSdiCwIOOYaEdnmvq6JXO57bsWucuKiozhigKypERcTxWGZKWze3zaY1DI2PaF1jMec7HTyS2ppaPa2ex5/MOlstHpKfEzrWiP+Ki6/c+aMoaiynoV3L+OMP74HdB6YjDGh1R/HmfwOuENVXxeR89zPpwLn4izVmwMcAzwIHCMiI4DbgFxAgVUi8rKqBrdcX5h8uqucw8elD6iR2DOz0vh4e9lBaduKa5k6+vNp32ePTcfrUzbvr2FeO4Eyr6iKiSOTSE/svHvu6TNHsWFvNSdNPTiYXDRvLJmp8VTVN1Pf1EKUCCflZARxV8aYYPTHYKKAv/I7Hdjrvl8EPKlON6HlIjJMRLJwAs1bqloOICJvAecAT4c1171Q3+RlfWEV3zp5SqSz0iMzs1J5YU0RFZ4mhifH4fMp20tqOTagN9qcbOcR5hVVtRtM1hdVdas09q2TpnDx/GzSkw4OOjHRUZwyLbODo4wx4dbvqrmAHwC/F5EC4A/ALW56NlAQsF+hm9ZRer+3pqCCFp9y9ABpL/GbMcYJFP4BhUWV9TQ0+w5adyV7WCLpibGtky8GqvA0UVjReeO7X2x0FFnp4Vtl0hjTOxEJJiKyRETy2nktAr4D/FBVxwM/BB7pw+te57bDrCwpKen6gBBbsbMCEbo1BUh/4u/Ou2mf0+i+zW18D1x3RUSYk53WOpgwkH9MiLVxGDN4RCSYqOpCVZ3Tzusl4BrgeXfX/wOOdt8XAYGLaYxz0zpKb++6D6lqrqrmZmZGvopkxa5yZoxJ67LdoL/JTI0nIyWOze7Suv5uwW1XhJwzNp3N+2oOGlwInze+z7HR6sYMGv2xmmsvcIr7/nTAP1jhZeBqt1fXsUCVqu4DFgNnichwERkOnOWm9WstXh+r91QMmPElbc3MSmPzfrdkcqCWjJR4hiUdPGBw1tg0mrw+th2oPSg9r6iKCSOSDmkHMcYMXN0KJiJyk4ikuV/kj4jIahE5K0R5+hbwRxH5DPg1cJ2b/hqwA8gH/gZ8F8BteL8TWOG+fuFvjO+vWrw+/rpsB3VNXo6aPLDaS/xmjElly4EaWrw+d5365EP28Y/7aNtusr6oyqq4jBlkutub6+uq+mcRORsYDnwVeAp4s68zpKofAEe2k67ADR0c8yjwaF/nJRTWF1ZxywvryCuq5owZo1joLtQ00MwYk0ZTi4+dpR7yD9Ry0fxD+zxMHplMclw0G/ZWc5mbVlnXREF5PVcePTG8GTbGhFR3g4l/0qjzgKdUdYP4hyObblu9p4JLH/yIkSnx3H/lAs6bO4aB+tfob4R/b2sJNY0t5Iw+dBr5qChxlv8NGAnvHzlvJRNjBpfuBpNVIvImMBm4RURSAV8Xx5g23tlUjIiw+AcnM2KAT0h42KhkYqKEV9Y5MwhPzTw0mIBT1fXsyoLWRa66M42KMWbg6W4w+QYwD9ihqnUiMhK4NnTZGpzWFlQyfXTqgA8kAPEx0UwdlcJnBZUATG2nZALOlPB1TV52lnmYOCKJj7aXWuO7MYNQt4KJqvpE5AAwS0T646j5fs/nUz4rqOTCef138auemjEmlc37a0hLiCEzJb7dffyLVb24pohlW0v4rLCKG0+bGs5sGmPCoFuBQUTuAr4MbAT8M/cpsCxE+Rp0dpTWUtPY0u7UIgPVzKw0Xly7l5zRqR22/eSMTiEuOoq/vJPPyOQ47rtyPufPzQpzTo0xodbdUsZFwHRVbQxlZgaz1Xuc6qD5EwZPMJnhNsLnjGq/iguc6VAuP3o8nkYvPztvBiM7KMEYYwa27gaTHUAsYMGkl9YWVJKaEMOUjI6/eAea2WPTiImSLhel+sWiOWHKkTEmUrobTOqAtSLyNgEBRVW/H5JcDUJr91RyxLhhRPXzpXl7IiMlntdvOomJIw8dsGiMGVq6G0xedl+mF+qaWthyoIbvnnpYpLPS53IC1jAxxgxdXQYTEYkGvqaqp4UhP4PS+sIqvD4dVI3vxhgTqMu5uVTVC/hExEaZ9dJadyyGBRNjzGDV3WquWmC9u4qhx59obSbds7agkvEjEq0nkzFm0OpuMHmez9cYMT20tqCSowbYaorGGNMT3R0B/0SoMzJY7a9qYF9Vg1VxGWMGte6OgN+JM+L9IKo6pc9zNMis3lMBwLxBNFjRGGPa6m41V27A+wTgMsDqbbrh6U/3kJESb0vUGmMGtW6ttKiqZQGvIlX9E3B+by8qIpeJyAYR8YlIbpttt4hIvohscRfj8qef46bli8jNAemTReQTN/1fItJvpuT9rKCS97eV8q2TJhMX0x9XSDbGmL7R3WV7FwS8ckXkerpfqmlPHnAJbSaKFJFZwOXAbOAc4AERiXbHutwPnAvMAq5w9wW4C7hHVacCFTjT5fcL9y/NJz0xlquOtVUFjTGDW3cDwh8D3rcAO4Ev9faiqroJaG+m2UXAM+6EkjtFJB842t2Wr6o73OOeARaJyCbgdOBKd58ngNuBB3ubt76yZX8Nb248wE1n5JASb7P2G2MGt24vjuX/IvcTkckhyE82sDzgc6GbBlDQJv0YYCRQqaot7ex/CBG5DrgOYMKECX2U5fY98G4+SXHRfO34SSG9jjHG9Afdrch/rptprURkiYjktfNa1PNs9g1VfUhVc1U1NzMzM2TX2V3m4ZXP9vKVYycyfBCsqmiMMV3ptGQiIjNw2i/SReSSgE1pOL26OqSqC3uRnyJgfMDncW4aHaSXAcNEJMYtnQTuHzHPrSpERPjmiaEovBljTP/TVTXXdOALwDDggoD0GuBbIcjPy8A/ReRuYCyQA3wKCJDjVq0V4TTSX6mqKiJLgUuBZ4BrgJdCkK8e+aywimmjUxmV1mm8NcaYQaPTYKKqLwEvichxqvpxX11URC4G/gJkAq+KyFpVPVtVN4jIszjLA7cAN7gTTSIiNwKLgWjgUVXd4J7up8AzIvJLYA3wSF/lszdUlXWFlZw9a0wks2GMMWHV3Qb4MndhrNGqOkdEDgcuVNVf9uaiqvoC8EIH234F/Kqd9NeA19pJ38HnPb4irrCinsq6ZuaOs0GKxpiho7sN8H8DbgGaAVR1HU5Vk2ljXWEVAEeMs+lTjDFDR3eDSZKqftomraXdPYe4dYWVxEVHMW3M4Fnr3RhjutLdYFIqIofhTvYoIpcC+0KWqwFsXWEVM7JSiY+JjnRWjDEmbLrbZnID8BAwQ0SKcEbAXxWyXA1QPp+SV1TFovljI50VY4wJq+6uZ7IDWCgiyTilmTqcNpPdIczbgLOzzENNYwuHZ1t7iTFmaOm0mktE0txZfO8TkTNxgsg1QD5BzM01WK13G9+tJ5cxZqjpqmTyFM5MvB/jDFK8FWcA4cWqujbEeRtw1hVWkRAbRc4oa3w3xgwtXQWTKao6F0BEHsZpdJ+gqg0hz9kAtK6wktlj04mJtrVLjDFDS1ffes3+N+5I9EILJO1r8frYsLeaudlWxWWMGXq6KpkcISLV7nsBEt3PAqiqpoU0dwPI9hIP9c1ejhhvwcQYM/R0NTeXDZbops8KKwGYaz25jDFDkFXu95Et+2tIjI1mSkZypLNijDFhZ8Gkj5TVNpKZGk9U1CFLERtjzKBnwaSPlNc126qKxpghy4JJH6nwNDEiKTbS2TDGmIiwYNJHyj1NVjIxxgxZEQkmInKZiGwQEZ+I5Aaknykiq0Rkvfvn6QHbjnTT80XkXhERN32EiLwlItvcP4dH4p4q6poYkWTBxBgzNEWqZJIHXAIsa5NeClzgjrq/Bmc6F78HcaZ0yXFf57jpNwNvq2oO8Lb7Oawamr3UNXmtZGKMGbIiEkxUdZOqbmknfY2q7nU/bsAZJBkvIllAmqouV1UFngQucvdbBDzhvn8iID1sKuqaABhhwcQYM0T15zaTLwKrVbURyAYKA7YVumngrEvvX6hrPzC6oxOKyHUislJEVpaUlPRZRss9TjAZbtVcxpghqruLY/WYiCwBxrSz6VZVfamLY2cDdwFn9eSaqqoiop1sfwhnkS9yc3M73K+nKjzOFGZWMjHGDFUhCyaqurA3x4nIOOAF4GpV3e4mFwHjAnYb56YBHBCRLFXd51aHFfc2z71V3lrNZV2DjTFDU7+q5hKRYcCrwM2q+qE/3a3GqhaRY91eXFcD/tLNyziN9bh/dlrqCYUKq+YyxgxxkeoafLGIFALHAa+KyGJ3043AVOB/RGSt+xrlbvsu8DDOKo/bgdfd9N8CZ4rINmCh+zmsyj1NiEB6opVMjDFDU8iquTqjqi/gVGW1Tf8l8MsOjlkJzGknvQw4o6/z2BMVdU2kJ8baoljGmCHLvv36QLnHBiwaY4Y2CyZ9oKLOplIxxgxtFkz6QLmn2RrfjTFDmgWTPlDhabJuwcaYIc2CSZBUlXKr5jLGDHEWTIJU1+SlqcVnDfDGmCHNgkmQWuflspKJMWYIs2ASpNYZg61kYowZwiyYBMlKJsYYY8EkaLaWiTHGWDAJWrl/+nmr5jLGDGEWTIJU4WkiOkpITYjINGfGGNMvWDAJUnldE8OTYomKkkhnxRhjIsaCSZAqPE02lYoxZsizYBKkco+NfjfGmEgtjnWZiGwQEZ+I5LazfYKI1IrIjwPSzhGRLSKSLyI3B6RPFpFP3PR/iUhYv9kr6mz6eWOMiVTJJA+4BFjWwfa7+XwlRUQkGrgfOBeYBVwhIrPczXcB96jqVKAC+EaoMt2eirpmK5kYY4a8iAQTVd2kqlva2yYiFwE7gQ0ByUcD+aq6Q1WbgGeARe568KcDz7n7PQFcFLqcH0xVbcZgY4yhn7WZiEgK8FPgjjabsoGCgM+FbtpIoFJVW9qkd3T+60RkpYisLCkpCTq/NY0ttPjUGuCNMUNeyIKJiCwRkbx2Xos6Oex2nCqr2lDkSVUfUtVcVc3NzMwM+nwVHhv9bowxACEbaaeqC3tx2DHApSLyO2AY4BORBmAVMD5gv3FAEVAGDBORGLd04k8PC5uXyxhjHP1q2LaqnuR/LyK3A7Wqep+IxAA5IjIZJ1hcDlypqioiS4FLcdpRrgFeCld+bcZgY4xxRKpr8MUiUggcB7wqIos7298tddwILAY2Ac+qqr+B/qfAj0QkH6cN5ZHQ5fxgrfNyWcnEGDPERaRkoqovAC90sc/tbT6/BrzWzn47cHp7hV2FVXMZYwzQz3pzDTTldU3ERUeRHBcd6awYY0xEWTAJQoWniWFJsTjDXYwxZuiyYBKEMk+TtZcYYwwWTIJSVtvIyBQLJsYYY8EkCOWeJkYmx0c6G8YYE3EWTIJg1VzGGOOwYNJLTS0+ahpaGGnBxBhjLJj0ln8qlRHWZmKMMRZMeqvM0whgJRNjjMGCSa/5SyYjU6wB3hhjLJj0UrlNP2+MMa0smPRSaa1bMrFgYowxFkx6q9zTSHSUkJZgS/YaY4wFk14qd8eYREXZvFzGGGPBpJfKapusissYY1wWTHrJRr8bY8znIrXS4mUiskFEfCKS22bb4SLysbt9vYgkuOlHup/zReReced9F5ERIvKWiGxz/xwejnsot2BijDGtIlUyyQMuAZYFJrprvf8duF5VZwOnAs3u5geBbwE57uscN/1m4G1VzQHedj+HXFlto1VzGWOMKyLBRFU3qeqWdjadBaxT1c/c/cpU1SsiWUCaqi5XVQWeBC5yj1kEPOG+fyIgPWSaWnxUN7TYgEVjjHH1tzaTaYCKyGIRWS0i/+2mZwOFAfsVumkAo1V1n/t+PzC6o5OLyHUislJEVpaUlPQ6kxV1NmDRGGMCxYTqxCKyBBjTzqZbVfWlTvJzInAUUAe8LSKrgKruXFNVVUS0k+0PAQ8B5ObmdrhfV8pswKIxxhwkZMFEVRf24rBCYJmqlgKIyGvAApx2lHEB+40Ditz3B0QkS1X3udVhxUFku1tsKhVjjDlYf6vmWgzMFZEktzH+FGCjW41VLSLHur24rgb8pZuXgWvc99cEpIdM64zB1mZijDFA5LoGXywihcBxwKsishhAVSuAu4EVwFpgtaq+6h72XeBhIB/YDrzupv8WOFNEtgEL3c8hZdVcxhhzsJBVc3VGVV8AXuhg299xqrXapq8E5rSTXgac0dd57Ey5p4noKCE90eblMsYY6H/VXANCmaeJ4UmxNi+XMca4LJj0Qrmn0RrfjTEmgAWTXnAmebTGd2OM8bNg0gvlniZGpFjJxBhj/CyY9EKZx6afN8aYQBZMeqjZ66OqvtnaTIwxJoAFkx6qcEe/24BFY4z5nAWTHirz2IBFY4xpy4JJD9m8XMYYcygLJj1kJRNjjDmUBZMeKqt1Jnm0kokxxnzOgkkPlXuaiBIYlmTBxBhj/CyY9JAzL1cc0TYvlzHGtLJg0kPltU1WxWWMMW1EZAr6gWzuuHQmZSRHOhvGGNOvRGpxrMtEZIOI+EQkNyA9VkSeEJH1IrJJRG4J2HaOiGwRkXwRuTkgfbKIfOKm/0tEQlpsuOG0qdx87oxQXsIYYwacSFVz5QGXAMvapF8GxKvqXOBI4NsiMklEooH7gXOBWcAVIjLLPeYu4B5VnQpUAN8Ixw0YY4z5XESCiapuUtUt7W0Ckt313xOBJqAaOBrIV9UdqtoEPAMscteDPx14zj3+CeCikN+AMcaYg/S3BvjnAA+wD9gD/EFVy4FsoCBgv0I3bSRQqaotbdLbJSLXichKEVlZUlISivwbY8yQFLIGeBFZAoxpZ9OtqvpSB4cdDXiBscBw4H33PH1CVR8CHgLIzc3VvjqvMcYMdSELJqq6sBeHXQm8oarNQLGIfAjk4pRKxgfsNw4oAsqAYSIS45ZO/OnGGGPCqL9Vc+3BaQNBRJKBY4HNwAogx+25FQdcDrysqgosBS51j78G6KjUY4wxJkQi1TX4YhEpBI4DXhWRxe6m+4EUEdmAE0AeU9V1bqnjRmAxsAl4VlU3uMf8FPiRiOTjtKE8Es57McYYA+L8uB96cnNzdeXKlZHOhjHGDCgiskpVcw9JH6rBRERKgN29PDwDKO3D7AwUQ/G+h+I9w9C8b7vn7pmoqpltE4dsMAmGiKxsLzIPdkPxvofiPcPQvG+75+D0twZ4Y4wxA5AFE2OMMUGzYNI7D0U6AxEyFO97KN4zDM37tnsOgrWZGGOMCZqVTIwxxgTNgokxxpigWTDpoY4W6RpMRGS8iCwVkY3uImY3uekjROQtEdnm/jk80nntayISLSJrROQ/7uewLr4WCSIyTESeE5HN7qJ0xw32Zy0iP3T/beeJyNMikjAYn7WIPCoixSKSF5DW7rMVx73u/a8TkQU9uZYFkx7oYpGuwaQF+C9VnYUzP9oN7n3eDLytqjnA2+7nweYmnCl7/IbC4mt/xplgdQZwBM79D9pnLSLZwPeBXFWdA0TjzPc3GJ/148A5bdI6erbnAjnu6zrgwZ5cyIJJz7S7SFeE89TnVHWfqq5239fgfLlk49zrE+5ug24hMhEZB5wPPOx+HvSLr4lIOnAy7px2qtqkqpUM8meNM2N6orsQXxLOGkqD7lmr6jKgvE1yR892EfCkOpbjzMie1d1rWTDpmY4W6Rq0RGQSMB/4BBitqvvcTfuB0RHKVqj8CfhvwOd+7tHiawPUZKAEeMyt3nvYnbF70D5rVS0C/oAzS/k+oApYxeB/1n4dPdugvt8smJgOiUgK8G/gB6paHbjNnf5/0PQrF5EvAMWquirSeQmzGGAB8KCqzsdZ6fSgKq1B+KyH4/wKn4yzEF8yh1YFDQl9+WwtmPRMEe0v0jXoiEgsTiD5h6o+7yYf8Bd73T+LI5W/EDgBuFBEduFUX56O05YwzK0KgcH5vAuBQlX9xP38HE5wGczPeiGwU1VL3IX4nsd5/oP9Wft19GyD+n6zYNIz7S7SFeE89Tm3reARYJOq3h2w6WWcBchgkC1Epqq3qOo4VZ2E81zfUdWrGOSLr6nqfqBARKa7SWcAGxnEzxqneutYEUly/63773lQP+sAHT3bl4Gr3V5dxwJVAdVhXbIR8D0kIufh1K1HA4+q6q8inKU+JyInAu8D6/m8/eBnOO0mzwITcKbv/5Kqtm3cG/BE5FTgx6r6BRGZglNSGQGsAb6iqo2RzF9fE5F5OJ0O4oAdwLU4PzQH7bMWkTuAL+P0XFwDfBOnfWBQPWsReRo4FWeq+QPAbcCLtPNs3cB6H06VXx1wrap2e9EnCybGGGOCZtVcxhhjgmbBxBhjTNAsmBhjjAmaBRNjjDFBs2BijDEmaBZMjAmCiHhFZG3Aq9MJEUXkehG5ug+uu0tEMoI9jzF9xboGGxMEEalV1ZQIXHcXzqy3peG+tjHtsZKJMSHglhx+JyLrReRTEZnqpt8uIj9233/fXTNmnYg846aNEJEX3bTlInK4mz5SRN501+B4GJCAa33FvcZaEfmrOGuyRIvI4+56HetF5IcR+GswQ4gFE2OCk9immuvLAduqVHUuzqjiP7Vz7M3AfFU9HLjeTbsDWOOm/Qx40k2/DfhAVWcDL+CMXkZEZuKM5D5BVecBXuAqYB6Qrapz3Dw81of3bMwhYrrexRjTiXr3S7w9Twf8eU8729cB/xCRF3GmuAA4EfgigKq+45ZI0nDWHLnETX9VRCrc/c8AjgRWOLNhkIgzcd8rwBQR+QvwKvBm72/RmK5ZycSY0NEO3vudj7Ny5wKcYNCbH3cCPKGq89zXdFW9XVUrcFZNfBen1PNwL85tTLdZMDEmdL4c8OfHgRtEJAoYr6pLgZ8C6UAKzgSbV7n7nAqUumvJLAOudNPPBfxrsr8NXCoio9xtI0RkotvTK0pV/w38HCdgGRMyVs1lTHASRWRtwOc3VNXfPXi4iKwDGoEr2hwXDfzdXTZXgHtVtVJEbgcedY+r4/Opwu8AnhaRDcBHONOoo6obReTnwJtugGoGbgDqcVZP9P9gvKXvbtmYQ1nXYGNCwLrumqHGqrmMMcYEzUomxhhjgmYlE2OMMUGzYGKMMSZoFkyMMcYEzYKJMcaYoFkwMcYYE7T/Dw8Zd+u4XkuhAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "epochs_list = list(range(len(return_list)))\n",
    "plt.plot(epochs_list, return_list)\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Returns')\n",
    "plt.title('CQL on {}'.format(env_name))\n",
    "plt.show()\n",
    "\n",
    "mv_return = rl_utils.moving_average(return_list, 9)\n",
    "plt.plot(episodes_list, mv_return)\n",
    "plt.xlabel('Episodes')\n",
    "plt.ylabel('Returns')\n",
    "plt.title('CQL on {}'.format(env_name))\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "第18章-离线强化学习.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
